﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;

namespace Sustainalytics.Synchronization.Interface
{
    public enum ErrorPolicy
    {
        BreakRightAway,
        CarryOn
    }

    public class SyncContext
    {
        private readonly List<ChangedElement> _changedElements = new List<ChangedElement>();
        private readonly Action<string> _logReport;

        public SyncContext()
        {
        }

        public SyncContext(ErrorPolicy errorPolicy, Action<string> logReport = null)
        {
            ErrorPolicy = errorPolicy;
            _logReport = logReport;
        }

        public bool LoggingEnabled => _logReport != null;

        public ErrorPolicy ErrorPolicy { get; private set; }

        public Dictionary<string, string> GAConnectionStrings { get; set; }

        public Dictionary<string,string> LastGAConnectionStrings { get; set; }

        public Dictionary<string, string> DSOConnectionStrings { get; set; }

        public Dictionary<Guid, List<int>> CompanyUniverses { get; set; }

        public List<Guid> DeletableCompanies { get; set; }

        public List<SyncStepOrder> SelectedSteps { get; set; }


        public DateTime? LastSyncTime { get; set; }
        public bool IsInitialSync { get; set; }

        public IEnumerable<ChangedElement> PreviousChanges { get; set; }

        public IEnumerable<ChangedElement> CurrentChanges
        {
            get { return _changedElements; }
        }

        public CancellationToken Token { get; set; }

        public SyncOperationStatus Status { get; set; }

        public double Progress { get; set; }

        public ConcurrentBag<string> Report { get; set; }

        public void AddChange(ChangedElement element)
        {
            _changedElements.Add(element);
        }

        public void AddManyChanges(IEnumerable<ChangedElement> elements)
        {
            _changedElements.AddRange(elements);
        }

        public void ResetCurrentChanges()
        {
            _changedElements.Clear();
        }

        public void Log(string msg)
        {
            Report.Add(msg);

            if (_logReport == null)
                return;

            _logReport(msg);
        }
    }
}
